home *** CD-ROM | disk | FTP | other *** search
-
- ; 3D cones, domes, dishes, spheres, and tori for AutoCAD 2.6 and later
-
- ; by Simon Jones - Autodesk UK Ltd.
- ; and Duff Kurland - Autodesk, Inc.
- ; November, 1986
-
- ; Combined into a single "3D" command - July, 1987
-
-
- (setq hemisphere nil ; Allow easier reloads
- domsph nil
- torus nil
- cone nil
- 3seg nil
- 4seg nil
- myerror nil
- C:3D nil)
-
-
- ; Syetem variable save
-
- (defun modes (a)
- (setq MLST nil)
- (repeat (length a)
- (setq MLST (append MLST (list (list (car a) (getvar (car a))))))
- (setq a (cdr a)))
- )
-
-
- ; Syetem variable restore
-
- (defun moder ()
- (repeat (length MLST)
- (setvar (caar MLST) (cadar MLST))
- (setq MLST (cdr MLST))
- )
- )
-
-
- ; Convert degrees to radians
-
- (defun dtr (a)
- (* pi (/ a 180.0))
- )
-
-
- ; Calculate new radius for dome/dish/sphere
-
- (defun calc-r (y)
- (sqrt (- (* rad rad) (* y y)))
- )
-
-
- ; Select all entities added since checkpoint.
-
- (defun selstuff (e)
- (setq ss nil) ; Free old selection-set if present
- (setq ss (ssadd)) ; Form empty selection-set
- (if (null e) ; No previous stuff in drawing?
- (setq ss (ssadd (setq e (entnext)) ss)) ; Start with what we drew
- )
- (while (setq e (entnext e)) ; Scan until end of drawing
- (setq ss (ssadd e ss)) ; Add each entity to selection-set
- )
- ss ; Return selection-set
- )
-
-
- ; Form a 3-point cone face
-
- (defun 3seg (/ pt2 pt3)
- (setq pt2 (polar cen 0.0 rmax))
- (setq pt3 (polar cen (dtr (/ 360.0 numseg)) rmax))
- (command "3DFACE"
- (list (car cen) (cadr cen) (+ elev h))
- (list (car pt2) (cadr pt2) elev)
- (list (car pt3) (cadr pt3) elev)
- ""
- ""
- )
- (setq doneface T)
- )
-
-
- ; Form a 4-point chopped-cone face
-
- (defun 4seg (/ pt1 pt2 pt3 pt4)
- (setq pt1 (polar cen 0.0 rmin))
- (setq pt2 (polar cen 0.0 rmax))
- (setq pt3 (polar cen (dtr (/ 360.0 numseg)) rmax))
- (setq pt4 (polar cen (dtr (/ 360.0 numseg)) rmin))
- (command "3DFACE"
- (list (car pt1) (cadr pt1) (+ elev h))
- (list (car pt2) (cadr pt2) elev)
- (list (car pt3) (cadr pt3) elev)
- (list (car pt4) (cadr pt4) (+ elev h))
- ""
- )
- (setq doneface T)
- )
-
-
- ; Build upper or lower hemisphere from chopped cones with decreasing radii.
-
- (defun hemisphere (which / baseelev h1 h2)
- (setq h2 (/ rad 4.0))
- (if (eq which "lower") ; Doing lower hemisphere?
- (setq h2 (- h2)) ; Yes, use negaitve height
- )
- (setq baseelev (caddr cen) elev baseelev h1 0 h (- h2 h1))
- (while (> (* rad rad) (* h2 h2))
- (setq rmax (calc-r h1) rmin (calc-r h2) h (- h2 h1))
- (4seg)
- (setq h1 h2 h2 (+ h2 (* h 0.85)))
- (setq elev (+ elev h) h (- h2 h1))
- )
-
- ; Now top it off.
-
- (setq rmax (calc-r h1))
- (if (eq which "upper")
- (setq h (- (+ baseelev rad) elev))
- (setq h (- (- baseelev rad) elev))
- )
- (3seg)
- )
-
-
- ; Draw a 3D cone
-
- (defun cone (/ cen elev h rmax rmin pt2 pt3 rad numseg)
- (initget (+ 1 16)) ; 3D point cannot be null
- (setq elev (caddr (setq cen (getpoint "\nBase center point: "))))
-
- (initget 7 "Diameter") ; Base radius can't be 0, neg, or null
- (setq rmax (getdist cen "\n<Base radius>/Diameter: "))
- (if (= rmax "Diameter")
- (progn
- (initget 7) ; Base diameter can't be 0, neg, or null
- (setq rmax (/ (getdist cen "\nBase diameter: ") 2.0))
- )
- )
-
- (initget 4 "Diameter") ; Top radius cannot be negative
- (setq rmin (getdist cen "\n<Top radius>/Diameter <0>: "))
- (if (= rmin "Diameter")
- (progn
- (initget 4) ; Top diameter cannot be negative
- (setq rmin (getdist cen "\nTop diameter <0>: "))
- (if rmin
- (setq rmin (/ rmin 2.0))
- )
- )
- )
-
- (initget 3) ; Height cannot be zero or null
- (setq h (getdist cen "\nHeight: "))
-
- (while (< numseg 3)
- (initget 6) ; Cannot have zero or negative segs
- (setq numseg (getint "\nNumber of segments <16>: "))
- (if (null numseg)
- (setq numseg 16)
- )
- (if (< numseg 3) (prompt "\nRequires at least 3 segments."))
- )
-
- (setvar "BLIPMODE" 0)
- (if rmin
- (4seg) ; Chopped off point
- (3seg) ; Full point
- )
- (command "ARRAY" (entlast) "" "Polar" cen numseg "360" "")
- )
-
-
- ; Generate a sphere or a hemisphere (dome/dish)
-
- (defun domsph (which name / cen e numseg rad)
- (setvar "THICKNESS" 0)
- (initget (+ 1 16)) ; Center point - 3d okay, cannot be null
- (setq cen (getpoint (strcat "\n" name " center point: ")))
-
- (initget 7) ; Radius cannot be zero, neg, or null
- (setq rad (getdist cen (strcat "\n" name " radius: ")))
-
- (while (or (< numseg 8) (> numseg 24))
- (initget 6) ; Cannot have zero or negative segs
- (setq numseg (getint "\nNumber of segments (8-24) <16>: "))
- (if (null numseg)
- (setq numseg 16)
- )
- (if (or (< numseg 8) (> numseg 24))
- (prompt "\nOutside acceptable range.")
- )
- )
-
- (setvar "BLIPMODE" 0)
- (setq e (entlast)) ; Take database checkpoint
- (if (= (logand which 1) 1) ; If sphere or dome,
- (hemisphere "upper") ; do upper hemisphere
- )
- (if (= (logand which 2) 2) ; If sphere or dish,
- (hemisphere "lower") ; do lower hemisphere
- )
- (command "ARRAY" (setq ss (selstuff e)) "" "Polar" cen numseg "360" "")
- (setq ss nil)
- )
-
-
- ; Draw a torus
-
- (defun torus (/ beta cen cosa deltal deltat e flop j numrseg numtseg
- px1 px2 px3 px4
- py1 py2 py3 py4
- pz1 pz2 pz3 pz4
- radl radt sina x xorg yorg zorg)
-
- (initget (+ 1 16)) ; Center point - 3D okay, cannot be null
- (setq cen (getpoint "\nTorus center point: "))
-
- (setq radl -1 radt 0)
- (while (> radt radl)
- (initget 7 "Diameter") ; Radius cannot be zero, neg, or null
- (setq radl (getdist cen "\n<Torus radius>/Diameter: "))
- (if (= radl "Diameter")
- (progn
- (initget 7) ; Diameter cannot be zero, neg, or null
- (setq radl (/ (getdist cen "\nTorus diameter: ") 2.0))
- )
- )
-
- (initget 7 "Diameter") ; Radius cannot be zero, neg, or null
- (setq radt (getdist cen "\n<Tube radius>/Diameter: "))
- (if (= radt "Diameter")
- (progn
- (initget 7) ; Diameter cannot be zero, neg, or null
- (setq radt (/ (getdist cen "\nTube diameter: ") 2.0))
- )
- )
- (if (> radt radl)
- (prompt "\nTube radius cannot exceed torus radius.")
- )
- )
-
- (while (or (< numrseg 8) (> numrseg 24))
- (initget 6) ; Cannot have zero or negative segs
- (setq numrseg (getint "\nNumber of radial segments (8-24) <16>: "))
- (if (null numrseg)
- (setq numrseg 16)
- )
- (if (or (< numrseg 8) (> numrseg 24))
- (prompt "\nOutside acceptable range.")
- )
- )
-
- (while (or (< numtseg 8) (> numtseg 24))
- (initget 6) ; Cannot have zero or negative segs
- (setq numtseg (getint "\nNumber of tube segments (8-24) <16>: "))
- (if (null numtseg)
- (setq numtseg 16)
- )
- (if (or (< numtseg 8) (> numtseg 24))
- (prompt "\nOutside acceptable range.")
- )
- )
-
- (setvar "BLIPMODE" 0)
- (setq e (entlast) ; Take database checkpoint
- deltat (* 2.0 (/ pi numtseg))
- deltal (* 2.0 (/ pi numrseg))
- cosa (cos deltal)
- sina (sin deltal)
- xorg (car cen)
- yorg (cadr cen)
- zorg (caddr cen)
- x (+ radl radt)
- px1 (+ x xorg)
- py1 yorg
- pz1 zorg
- px2 (+ xorg (* x cosa))
- py2 (+ yorg (* x sina))
- pz2 pz1
- )
- (command "3DFACE" (list px1 py1 pz1) (list px2 py2 pz2))
-
- (setq doneface T j 1 flop 0)
- (while (<= j numtseg)
- (setq beta (* j deltat)
- x (+ radl (* radt (cos beta)))
- px3 (+ xorg (* x cosa))
- py3 (+ yorg (* x sina))
- pz3 (+ zorg (* radt (sin beta)))
- px4 (+ xorg x)
- py4 yorg
- pz4 pz3
- )
- (if (= 1 flop)
- (command (list px4 py4 pz4) (list px3 py3 pz3))
- (command (list px3 py3 pz3) (list px4 py4 pz4))
- )
- (setq flop (- 1 flop) j (+ j 1))
- )
- (command "")
- (command "ARRAY" (setq ss (selstuff e)) "" "Polar" cen numrseg "360" "Y")
- (setq ss nil)
- )
-
-
- ; Internal error handler
-
- (defun myerror (s) ; If an error (such as CTRL-C) occurs
- ; while this command is active...
- (if (/= s "Function cancelled")
- (princ (strcat "\nError: " s))
- )
- (if doneface
- (progn ; If we're drawing 3DFACEs...
- (command) ; simulate CTRL-C (cancel 3DFACE cmd)
- (command "UNDO" "End") ; terminate Undo group
- (princ " ...undoing ") ; erase partially-drawn stuff
- (command "U")
- )
- )
- (moder) ; Restore modified modes
- (setq ss nil) ; Free selection-set if any
- (setq *error* olderr) ; Restore old *error* handler
- (princ)
- )
-
-
- (defun C:CONE () (3d "Cone"))
- (defun C:DISH () (3d "DIsh"))
- (defun C:DOME () (3d "DOme"))
- (defun C:SPHERE () (3d "Sphere"))
- (defun C:TORUS () (3d "Torus"))
- (defun C:3D () (3d nil))
-
-
- ; Main program. Draws 3D object specified by "key" argument.
- ; If "key" is nil, asks which object is desired.
-
- (defun 3d (key / doneface olderr ss)
- (setq olderr *error*
- *error* myerror
- doneface nil)
- (modes '("CMDECHO" "BLIPMODE" "HIGHLIGHT" "ELEVATION" "THICKNESS"))
- (setvar "CMDECHO" 0)
- (setvar "HIGHLIGHT" 0)
- (if (null key)
- (progn
- (initget "Cone DIsh DOme Sphere Torus")
- (prompt "\nSelect 3D utility.")
- (setq key (getkword "\nCone/DIsh/DOme/Sphere/Torus: "))
- )
- )
- (cond ((= key "Cone") (cone))
- ((= key "DIsh") (domsph 2 "Dish"))
- ((= key "DOme") (domsph 1 "Dome base"))
- ((= key "Sphere") (domsph 3 key))
- ((= key "Torus") (torus))
- (T nil) ; Null reply? Just exit
- )
- (moder) ; Restore saved modes
- (setq *error* olderr) ; Restore old *error* handler
- (princ)
- )
-